package joc.internal.util;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class AnnotationInstantiator {
	public static <T extends Annotation> T getAnnotation(Class<T> annotationClass, final Object... values) {
		return getAnnotationArrayAccessible(annotationClass, values);
	}
	
	public static <T extends Annotation> T getAnnotationArrayAccessible(Class<T> annotationClass) {
		return getAnnotationArrayAccessible(annotationClass, new Object[] {});
	}
	
	@SuppressWarnings("unchecked")
	public static <T extends Annotation> T getAnnotationArrayAccessible(Class<T> annotationClass, final Object[] values) {
		final List<String> annotationMethods = new ArrayList<String>();
		for (Method annotationMethod : annotationClass.getDeclaredMethods()) {
			annotationMethods.add(annotationMethod.getName());
		}
		Collections.sort(annotationMethods);
		return (T) Proxy.newProxyInstance(annotationClass.getClassLoader(), new Class[] { annotationClass }, new InvocationHandler() {
			@Override
			public Object invoke(Object obj, Method method, Object[] args)
					throws Throwable {
				return values[annotationMethods.indexOf(method.getName())];
			}
		});
	}
}
